package com.jpush.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.SecurityWebFiltersOrder;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatcher;
import org.springframework.security.web.server.util.matcher.ServerWebExchangeMatchers;

@EnableWebFluxSecurity
public class WebFluxSecurityConfiguration {


    @Autowired
    SpringSecurityTemplate springSecurityTemplate;
    @Bean
    public SecurityWebFilterChain apiWebFilterChain(ServerHttpSecurity http) {
        ServerWebExchangeMatcher ignoreMatcher = ServerWebExchangeMatchers.pathMatchers("/spring-manager/actuator/**");
        ServerWebExchangeMatcher matcher = exchange -> ignoreMatcher.matches(exchange).flatMap(r -> {
            if (r.isMatch()) {
                return ServerWebExchangeMatcher.MatchResult.notMatch();
            } else {
                return ServerWebExchangeMatcher.MatchResult.match();
            }
        });

        return http.securityMatcher(matcher)
                .csrf().disable()
                .headers().disable()
                .requestCache().disable()
                .logout().logoutUrl("/logout").logoutHandler(new WebFluxServerLogoutHandler())// 只能用post方式退出
                .logoutSuccessHandler(new WebFluxServerLogoutSuccessHandler())
                .and()
                .addFilterBefore(new WebFluxLoginFilter(springSecurityTemplate), SecurityWebFiltersOrder.HTTP_BASIC)
                .addFilterAt(new WebFluxTokenAuthenticationFilter(springSecurityTemplate), SecurityWebFiltersOrder.HTTP_BASIC)
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .exceptionHandling().authenticationEntryPoint((webFilterExchange, exception) -> {
                    throw exception;
                })
                .and()
                .build();
    }
}
